package ecs

import (
	"os"
	"sieve_engine/lib/aliyun"
	"sieve_engine/lib/config"
	"strings"
)

var (
	fInstanceId = config.String("aliyun.ecs.id", detectInstanceId(), "阿里云 ECS 实例ID")
	fEndpoint   = config.String("aliyun.ecs.endpoint", "ecs.aliyuncs.com", "阿里云 ECS API域名")
)

func detectInstanceId() string {
	name, err := os.Hostname()
	if err != nil {
		return ""
	}
	return strings.Replace(name, "Z", "-", -1)[:len(name)-1]
}

func InstanceId() string {
	return *fInstanceId
}

type getAllResp struct {
	PageNumber int
	TotalCount int
	PageSize   int
	Instances  struct {
		Instance []*instanceResp
	}
}

type instanceResp struct {
	InstanceId        string
	InstanceName      string
	Description       string
	Cpu               int
	Memory            int
	Status            string
	NetworkInterfaces struct {
		NetworkInterface []*struct {
			MacAddress       string
			PrimaryIpAddress string
		}
	}
	PublicIpAddress struct {
		IpAddress []string
	}
	InternetMaxBandwidthOut int
}

func (r *instanceResp) Detail() *InstanceDetail {
	detail := &InstanceDetail{
		InstanceId:   r.InstanceId,
		InstanceName: r.InstanceName,
		Description:  r.Description,
		Cpu:          r.Cpu,
		Memory:       r.Memory,
		Status:       r.Status,
	}
	if ifs := r.NetworkInterfaces.NetworkInterface; ifs != nil && len(ifs) > 0 {
		detail.Mac = ifs[0].MacAddress
		detail.LocalIP = ifs[0].PrimaryIpAddress
	}
	if ips := r.PublicIpAddress.IpAddress; ips != nil && len(ips) > 0 {
		detail.PublicIP = ips[0]
		detail.Bandwidth = r.InternetMaxBandwidthOut
	}
	return detail
}

func GetAllInstances() ([]*InstanceDetail, error) {
	list := []*InstanceDetail{}
	page := 1
	for {
		resp := &getAllResp{}
		if err := aliyun.ReqApi(*fEndpoint, "DescribeInstances", map[string]any{
			"Version":    "2014-05-26",
			"RegionId":   aliyun.Region(),
			"PageNumber": page,
			"PageSize":   100,
		}, resp); err != nil {
			return nil, err
		}
		if resp.Instances.Instance == nil {
			break
		}

		for _, r := range resp.Instances.Instance {
			list = append(list, r.Detail())
		}

		if resp.PageNumber*resp.PageSize >= resp.TotalCount {
			break
		}
		page += 1
	}

	return list, nil
}

type InstanceDetail struct {
	InstanceId   string
	InstanceName string
	Description  string
	Cpu          int
	Memory       int
	Mac          string
	LocalIP      string
	PublicIP     string
	Bandwidth    int
	Status       string
}
